﻿using System;
using System.IO;
using System.Xml;
using System.Xml.Serialization;

namespace Rail.Commons.SerializeHelper
{
    /// <summary>
    /// Xml 序列化和反序列化类
    /// </summary>
    public class XmlHelper
    {
        /// <summary>
        /// 序列化对象为XML文件
        /// </summary>
        /// <typeparam name="T">序列化对象</typeparam>
        /// <param name="fileName">序列化文件路径</param>
        /// <param name="t">序列化对象</param>
        /// <returns></returns>
        public static bool SerializedToXml<T>(string fileName, T t)
        {
            try
            {
                Type paramType = t.GetType();
                XmlSerializer xmls = new XmlSerializer(paramType);
                using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write))
                {
                    xmls.Serialize(fs, t);
                }
                return true;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine("Serialize xml Error：" + ex.ToString());
                return false;
            }
        }

        /// <summary>
        /// 反序列化对象
        /// </summary>
        /// <typeparam name="T">反序列化的对象</typeparam>
        /// <param name="fileName">反序列化文件的路径</param>
        /// <param name="t">反序列化出来的路径</param>
        /// <returns></returns>
        public static bool DeSerializedFromXml<T>(string fileName, ref T t)
        {
            try
            {
                Type paramType = t.GetType();
                XmlSerializer xmls = new XmlSerializer(paramType);

                using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read))
                {
                    t = (T)xmls.Deserialize(fs);
                }
                return true;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine("DeSerialize xml Error：" + ex.ToString());
                return false;
            }
        }
        public static string Context(string path)
        {
            var xmlDoc = new XmlDocument();
            xmlDoc.Load(path);
            return xmlDoc.OuterXml;
        }

        protected string strXmlFile;
        protected XmlDocument objXmlDoc = new XmlDocument();

        public XmlHelper(string XmlFile)
        {
            //
            // TODO: 在这里加入建构函式的程序代码
            //
            try
            {

                objXmlDoc.Load(XmlFile);
            }
            catch (System.Exception ex)
            {
                throw ex;
            }
            strXmlFile = XmlFile;
        }
        /// <summary>
        /// 新节点内容。
        /// 示例：xmlTool.Replace("Book/Authors[ISBN=\"0002\"]/Content","ppppppp");
        /// </summary>
        /// <param name="XmlPathNode"></param>
        /// <param name="Content"></param>
        public void Replace(string XmlPathNode, string Content)
        {
            //更新节点内容。
            objXmlDoc.SelectSingleNode(XmlPathNode).InnerText = Content;
        }

        public string GetNodeContent(string fullPath)
        {
            return objXmlDoc.SelectSingleNode(fullPath).InnerText;
        }

        /// <summary>
        /// 删除一个指定节点的子节点。
        /// 示例： xmlTool.DeleteChild("Book/Authors[ISBN=\"0003\"]");
        /// </summary>
        /// <param name="Node"></param>
        public void DeleteChild(string Node)
        {
            //删除一个节点。
            string mainNode = Node.Substring(0, Node.LastIndexOf("/"));
            objXmlDoc.SelectSingleNode(mainNode).RemoveChild(objXmlDoc.SelectSingleNode(Node));
        }



        /// <summary>

        ///  * 使用示列:
        ///  示例： XmlHelper.Delete( "/Node", "")
        ///  XmlHelper.Delete( "/Node", "Attribute")
        /// </summary>
        /// <param name="node">节点</param>
        /// <param name="attribute">属性名，非空时删除该节点属性值，否则删除节点值</param>
        public void Delete(string node, string attribute)
        {
            try
            {

                XmlNode xn = objXmlDoc.SelectSingleNode(node);
                XmlElement xe = (XmlElement)xn;
                if (attribute.Equals(""))
                    xn.ParentNode.RemoveChild(xn);
                else
                    xe.RemoveAttribute(attribute);

            }
            catch { }
        }


        /// <summary>
        /// 插入一节点和此节点的一子节点。
        /// 示例：xmlTool.InsertNode("Book","Author","ISBN","0004");
        /// </summary>
        /// <param name="MainNode">主节点</param>
        /// <param name="ChildNode">子节点</param>
        /// <param name="Element">元素</param>
        /// <param name="Content">内容</param>
        public void InsertNode(string MainNode, string ChildNode, string Element, string Content)
        {
            //插入一节点和此节点的一子节点。
            XmlNode objRootNode = objXmlDoc.SelectSingleNode(MainNode);
            XmlElement objChildNode = objXmlDoc.CreateElement(ChildNode);
            objRootNode.AppendChild(objChildNode);
            XmlElement objElement = objXmlDoc.CreateElement(Element);
            objElement.InnerText = Content;
            objChildNode.AppendChild(objElement);
        }
        public XmlNode GetNode(string MainNode)
        {
            return objXmlDoc.SelectSingleNode(MainNode);
        }
        /// <summary>
        /// 插入一个节点，带一属性。
        /// 示例： xmlTool.InsertElement("Book/Author[ISBN=\"0004\"]","Title","Sex","man","iiiiiiii");
        /// </summary>
        /// <param name="MainNode">主节点</param>
        /// <param name="Element">元素</param>
        /// <param name="Attrib">属性</param>
        /// <param name="AttribContent">属性内容</param>
        /// <param name="Content">元素内容</param>
        public XmlElement InsertElement(string MainNode, string Element, string Attrib, string AttribContent, string Content)
        {
            //插入一个节点，带一属性。
            XmlNode objNode = objXmlDoc.SelectSingleNode(MainNode);
            XmlElement objElement = objXmlDoc.CreateElement(Element);
            objElement.SetAttribute(Attrib, AttribContent);
            objElement.InnerText = Content;
            objNode.AppendChild(objElement);
            return objElement;
        }
        /// <summary>
        /// 插入一个节点，不带属性。
        /// 示例：xmlTool.InsertElement("Book/Author[ISBN=\"0004\"]","Content","aaaaaaaaa");
        /// </summary>
        /// <param name="MainNode">主节点</param>
        /// <param name="Element">元素</param>
        /// <param name="Content">元素内容</param>
        public void InsertElement(string MainNode, string Element, string Content)
        {
            //插入一个节点，不带属性。
            XmlNode objNode = objXmlDoc.SelectSingleNode(MainNode);
            XmlElement objElement = objXmlDoc.CreateElement(Element);
            objElement.InnerText = Content;
            objNode.AppendChild(objElement);
        }

        /// <summary>
        /// 对xml文件做插入，更新，删除后需做Save()操作，以保存修改
        /// </summary>
        public void Save()
        {
            //保存文檔。
            try
            {
                objXmlDoc.Save(strXmlFile);
            }
            catch (System.Exception ex)
            {
                throw ex;
            }
        }
    }
}